package com.dhz.common.utils.http;

import org.apache.commons.lang3.StringUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * @author fyduan
 * @date 16/3/23
 */
public class HttpHelper {

    // -------------------------- 通用常量 ------------------------------
    public static final String HTTP = "http://";
    public static final String HTTPS = "https://";

    public static final String USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36";
    // -------- Accept 只出现在Request中 : 浏览器端可以接受的媒体类型 -------
    public static final String ACCEPT_ALL = "*/*";
    public static final String ACCEPT_IMAGE = "image/webp,image/*,*/*;q=0.8";
    public static final String ACCEPT_HTML = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
    public static final String ACCEPT_JSON = "application/json, text/javascript, */*; q=0.01";

    public static final String CONTENT_TYPE_REQUEST = "application/x-www-form-urlencoded";
    public static final String CONTENT_TYPE_UTF8_REQUEST = "application/x-www-form-urlencoded; charset=UTF-8";

    // -------------------- Util method --------------------

    /**
     * 获得请求URL中的queryParam部分某一个可以对应的值.
     *
     * @param query {@link String} URL中的查询参数
     * @param key   {@link String} 要查询的KEY
     * @return      {@link String} param
     */
    public static String getQueryParamByKey(String query, String key) {
        if (StringUtils.isBlank(query) || StringUtils.isBlank(key)) {
            return null;
        }

        int idx = query.indexOf("?"), len = query.length(), i;
        query = (idx != -1 && (idx += 1) < len - 1) ? query.substring(idx) : null;
        if (StringUtils.isBlank(query)) return null;

        String[] params = query.split("&");
        String[] _param;
        for (i = 0, len = params.length; i < len; i++) {
            _param = params[i].split("=");
            if (key.equals(_param[0])) {
                return _param.length == 1 ? "" : _param[1];
            }
        }
        return null;
    }

    /**
     * 获得请求URL中的queryParams部分的Map对象.
     *
     * @param query {@link String} URL中的查询参数
     * @return      {@link String} param
     */
    public static Map<String, String> getQueryParamsMap(String query) {
        if (StringUtils.isBlank(query)) {
            return null;
        }

        int idx = query.indexOf("?"), len = query.length(), i;
        query = (idx != -1 && (idx += 1) < len - 1) ? query.substring(idx) : null;
        if (StringUtils.isBlank(query)) return null;

        Map<String, String> paramsMap = new HashMap<String, String>();

        String[] params = query.split("&");
        String[] _param;
        for (i = 0, len = params.length; i < len; i++) {
            _param = params[i].split("=");
            paramsMap.put(_param[0], _param.length == 2 ? _param[1] : "");
        }

        return paramsMap;
    }

    // Http协议常用头部枚举字段
    public enum Header {
        // ----------------------------- 通用头域 --------------------------------

        /** 提供日期和时间标志,说明报文是什么时间创建的 */
        DATE("Date"),
        /** 允许客户端和服务器指定与请求/响应连接有关的选项 */
        CONNECTION("Connection"),
        /** 给出发送端使用的MIME版本 */
        MIME_VERSION("MIME-Version"),
        /** 如果报文采用了分块传输编码(chunked transfer encoding) 方式,就可以用这个首部列出位于报文拖挂(trailer)部分的首部集合 */
        TRAILER("Trailer"),
        /** 告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式 */
        TRANSFER_ENCODING("Transfer-Encoding"),
        /** 给出了发送端可能想要"升级"使用的新版本和协议 */
        UPGRADE("Upgrade"),
        /** 显示了报文经过的中间节点 */
        VIA("Via"),
        /** 指定请求和响应遵循的缓存机制 */
        CACHE_CONTROL("Cache-Control"),
        /** 用来包含实现特定的指令，最常用的是Pragma:no-cache。在HTTP/1.1协议中，它的含义和Cache- Control:no-cache相同 */
        PRAGMA("Pragma"),
        /** 请求表示提交内容类型或返回返回内容的MIME类型 */
        CONTENT_TYPE("Content-Type"),

        // ----------------------------- Request Header Start --------------------------------
        /**
         * 指定请求资源的Intenet主机和端口号，必须表示请求url的原始服务器或网关的位置。
         * HTTP/1.1请求必须包含主机头域，否则系统会以400状态码返回
         */
        HOST("Host"),
        /**
         * 允许客户端指定请求uri的源资源地址，这可以允许服务器生成回退链表，可用来登陆、优化cache等。
         * 他也允许废除的或错误的连接由于维护的目的被 追踪。如果请求的uri没有自己的uri地址，Referer不能被发送。
         * 如果指定的是部分uri地址，则此地址应该是一个相对地址
         */
        REFERER("Referer"),
        /**
         * HTTP客户端运行的浏览器类型的详细信息。
         * 通过该头部信息，web服务器可以判断到当前HTTP请求的客户端浏览器类别
         */
        USER_AGENT("User-Agent"),
        /** 指定客户端能够接收的内容类型，内容类型中的先后次序表示客户端接收的先后次序 */
        ACCEPT("Accept"),
        /** 指定HTTP客户端浏览器用来展示返回信息所优先选择的语言 */
        ACCEPT_LANGUAGE("Accept-Language"),
        /** 指定客户端浏览器可以支持的web服务器返回内容压缩编码类型 */
        ACCEPT_ENCODING("Accept-Encoding"),
        /** 浏览器可以接受的字符编码集*/
        ACCEPT_CHARSET("Accept-Charset"),
        /** HTTP请求发送时，会把保存在该请求域名下的所有cookie值一起发送给web服务器 */
        COOKIE("Cookie"),
        /** 请求的内容长度 */
        CONTENT_LENGTH("Content-Length"),
        /** 与#Referer功能近似,但只用于POST请求中 */
        ORIGIN("Origin"),

        // ----------------------------- Response Header Start --------------------------------
        /** 响应后服务端新增的Cookie */
        SET_COOKIE("Set-Cookie"),
        /** 是用于在数据源和数据最终接收者之间传递编码方式的。
         * 中间代理（如果有的话）不会去试图解码，而只是原样传输。
         * 如: Content-Encoding: gzip,deflate,compress
         */
        CONTENT_ENCODING("Content-Encoding"),
        /** ETag是一个可以与Web资源关联的记号（token） */
        ETAG("ETag"),
        /** 重定向地址 */
        LOCATION("Location")
        ;

        // ----------------------------- Base --------------------------------
        private String value;
        Header(String value) {
            this.value = value;
        }
        public String getValue() {
            return value;
        }
    }

}
